////////////////////////////////////////////////////////////////////////////////////////////////////
/// Copyright (c) 2009 - 2010 RacoonStudios
///
/// Permission is hereby granted, free of charge, to any person obtaining a copy of this
/// software and associated documentation files (the "Software"), to deal in the Software
/// without restriction, including without limitation the rights to use, copy, modify, merge,
/// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
/// to whom the Software is furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in all copies or
/// substantial portions of the Software.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
/// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
/// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
/// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
/// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
/// DEALINGS IN THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////////////////////////

#pragma once
#ifndef uri_h__
#define uri_h__

#include "Core/types.h"
#include "Helper/string.h"

namespace IO
{
	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// \class	URI
	///
	/// \brief	This is an implementation of the so called Uniform Resource Identifier.
	///			This URI has the following structure:
	///
	///			Scheme://UserInfo@Host:Port/LocalPath#Fragment?Query
	///
	///			We use this because we have a wide mass of possibilities to get our resources
	///			from. The local hdd, ad blue ray, dvd, a web server, or anything else.
	///
	///			If you want more information about this topic you just have to visit this page:
	///			http://de.wikipedia.org/wiki/Uniform_Resource_Identifier
	///
	///			And here also some example how an URI have to look:
	///			http://de.wikipedia.org/wiki/Uniform_Resource_Identifier ;)
	///			ftp://ftp.example.de/bla/blubb.txt
	///			mailto:webmaster@racoon-games.de
	///
	/// \author	khaos
	/// \date	30.11.2009
	////////////////////////////////////////////////////////////////////////////////////////////////////
	class URI
	{
		public:

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	URI()
			///
			/// \brief	Constructor.
			///
			/// \author	khaos
			/// \date	05.01.2010
			////////////////////////////////////////////////////////////////////////////////////////////////////
			URI();

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	URI(const URI & rhs)
			///
			/// \brief	Copy constructor. 
			///
			/// \author	khaos
			/// \date	05.01.2010
			///
			/// \param	[in]	rhs	The right hand side object. 
			////////////////////////////////////////////////////////////////////////////////////////////////////
			URI(const URI & rhs);

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	URI(const Helper::String & rhs)
			///
			/// \brief	Constructor. 
			///
			/// \author	khaos
			/// \date	05.01.2010
			///
			/// \param	[in]	rhs	The right hand side object. 
			////////////////////////////////////////////////////////////////////////////////////////////////////
			URI(const Helper::String & rhs);




			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	void operator= (const URI & rhs)
			///
			/// \brief	Copy operator. 
			///
			/// \author	khaos
			/// \date	05.01.2010
			///
			/// \param	[in]	rhs	The right hand side object. 
			////////////////////////////////////////////////////////////////////////////////////////////////////
			void operator = (const URI & rhs);

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	bool operator== (const URI & rhs) const
			///
			/// \brief	Equality operator. 
			///
			/// \author	khaos
			/// \date	05.01.2010
			///
			/// \param	[in]	rhs	The right hand side. 
			///
			/// \return	True if both are the same, otherwise false.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			bool operator == (const URI & rhs) const;

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	bool operator!= (const URI & rhs) const
			///
			/// \brief	Inequality operator. 
			///
			/// \author	khaos
			/// \date	05.01.2010
			///
			/// \param	[in]	rhs	The right hand side. 
			///
			/// \return	True if both are inequal, otherwise false.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			bool operator != (const URI & rhs) const;




			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	bool IsEmpty() const
			///
			/// \brief	Returns true id the URI is empty.
			///
			/// \author	khaos
			/// \date	05.01.2010
			///
			/// \return	True if URI is empty, otherwise false.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			bool IsEmpty() const;

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	bool IsValid() const
			///
			/// \brief	Returns true if this URI is valid.
			///
			/// \author	khaos
			/// \date	05.01.2010
			///
			/// \return	True if URI is valid, otherwise false.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			bool IsValid() const;

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	void Clear()
			///
			/// \brief	Clears this URI.
			///
			/// \author	khaos
			/// \date	05.01.2010
			////////////////////////////////////////////////////////////////////////////////////////////////////
			void Clear();




			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	void SetScheme(const Helper::String & scheme)
			///
			/// \brief	Sets the scheme of the URI.
			///
			/// \author	khaos
			/// \date	05.01.2010
			///
			/// \param	[in]	scheme	The scheme this URI should have.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			void SetScheme(const Helper::String & scheme);

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	void SetUserInfo(const Helper::String & userinfo)
			///
			/// \brief	Sets the user information od the URI.
			///
			/// \author	khaos
			/// \date	05.01.2010
			///
			/// \param	[in]	userinfo	The userinfo this URI should have.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			void SetUserInfo(const Helper::String & userinfo);

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	void SetHost(const Helper::String & host)
			///
			/// \brief	Sets the host of the URI.
			///
			/// \author	khaos
			/// \date	05.01.2010
			///
			/// \param	[in]	host	The host this URI should have.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			void SetHost(const Helper::String & host);

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	void SetPort(const Helper::String & port)
			///
			/// \brief	Sets the port of the URI.
			///
			/// \author	khaos
			/// \date	05.01.2010
			///
			/// \param	[in]	port	The port this URI should have.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			void SetPort(const Helper::String & port);

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	void SetLocalPath(const Helper::String & path)
			///
			/// \brief	Sets the local path of the URI.
			///
			/// \author	khaos
			/// \date	05.01.2010
			///
			/// \param	[in]	path	Full pathname of the file. 
			////////////////////////////////////////////////////////////////////////////////////////////////////
			void SetLocalPath(const Helper::String & path);

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	void SetFragment(const Helper::String & frag)
			///
			/// \brief	Sets the fragment of the URI.
			///
			/// \author	khaos
			/// \date	05.01.2010
			///
			/// \param	[in]	frag	The fragment this URI should have.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			void SetFragment(const Helper::String & frag);

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	void SetQuery(const Helper::String & query)
			///
			/// \brief	Sets the query of the URI.
			///
			/// \author	khaos
			/// \date	05.01.2010
			///
			/// \param	[in]	query	The query this URI should have.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			void SetQuery(const Helper::String & query);

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	const Helper::String & GetScheme() const
			///
			/// \brief	Returns the scheme.
			///
			/// \author	khaos
			/// \date	05.01.2010
			///
			/// \return	The scheme of this URI.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			const Helper::String & GetScheme() const;

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	const Helper::String & GetUserInfo() const
			///
			/// \brief	Returns the user information. 
			///
			/// \author	khaos
			/// \date	05.01.2010
			///
			/// \return	The user information of this URI.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			const Helper::String & GetUserInfo() const;

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	const Helper::String & GetHost() const
			///
			/// \brief	Returns the host. 
			///
			/// \author	khaos
			/// \date	05.01.2010
			///
			/// \return	The host of this URI.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			const Helper::String & GetHost() const;

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	const Helper::String & GetPort() const
			///
			/// \brief	Returns the port. 
			///
			/// \author	khaos
			/// \date	05.01.2010
			///
			/// \return	The port of this URI.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			const Helper::String & GetPort() const;

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	const Helper::String & GetLocalPath() const
			///
			/// \brief	Returns the local path. 
			///
			/// \author	khaos
			/// \date	05.01.2010
			///
			/// \return	The local path of this URI.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			const Helper::String & GetLocalPath() const;

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	const Helper::String & GetFragment() const
			///
			/// \brief	Returns the fragment. 
			///
			/// \author	khaos
			/// \date	05.01.2010
			///
			/// \return	The fragment of this URI.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			const Helper::String & GetFragment() const;

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	const Helper::String & GetQuery() const
			///
			/// \brief	Returns the query. 
			///
			/// \author	khaos
			/// \date	05.01.2010
			///
			/// \return	The query of this URI.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			const Helper::String & GetQuery() const;




			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	void Set(const Helper::String & str)
			///
			/// \brief	Defines the URI by getting the data from a String.
			///
			/// \author	khaos
			/// \date	05.01.2010
			///
			/// \param	[in]	str	The const Helper::String & to set. 
			////////////////////////////////////////////////////////////////////////////////////////////////////
			void Set(const Helper::String & str);

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	Helper::String GetAsString() const
			///
			/// \brief	Returns a String with all parts of the URI.
			///
			/// \author	khaos
			/// \date	05.01.2010
			///
			/// \return	A String containing the whole Scheme.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			Helper::String GetAsString() const;

		protected:

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	protected: bool Split(const Helper::String & str)
			///
			/// \brief	Splits the specified String.
			///
			/// \author	khaos
			/// \date	05.01.2010
			///
			/// \param	[in]	str	The string. 
			///
			/// \return	True if the specified String is a valid URI.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			bool Split(const Helper::String & str);

			////////////////////////////////////////////////////////////////////////////////////////////////////
			/// \fn	Helper::String Build() const
			///
			/// \brief	Builds a single String from all data.
			///
			/// \author	khaos
			/// \date	05.01.2010
			///
			/// \return	A Scheme-String containing all valid elements of this URI.
			////////////////////////////////////////////////////////////////////////////////////////////////////
			Helper::String Build() const;




			Helper::String m_scheme;
			Helper::String m_userinfo;
			Helper::String m_host;
			Helper::String m_port;
			Helper::String m_localpath;
			Helper::String m_fragment;
			Helper::String m_query;

			bool m_isEmpty;

		private:

	};

}

#endif // uri_h__